﻿namespace JoinBox.Basal;

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;


// https://q.cnblogs.com/q/46971/
public partial class Intranet
{
    [StructLayout(LayoutKind.Sequential)]
    protected struct SHARE_INFO_1
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string shi1_netname;
        [MarshalAs(UnmanagedType.U4)]
        public uint shi1_type;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string shi1_remark;
    }
#pragma warning disable CA1401 // P/Invokes 应该是不可见的
    [DllImport("Netapi32.dll", CharSet = CharSet.Auto)]// EntryPoint = "NetShareEnum"
    protected static extern int NetShareEnum(
        [MarshalAs(UnmanagedType.LPWStr)] string servername,
        [MarshalAs(UnmanagedType.U4)] uint level,
        out IntPtr bufptr,
        [MarshalAs(UnmanagedType.U4)] int prefmaxlen,
        [MarshalAs(UnmanagedType.U4)] out uint entriesread,
        [MarshalAs(UnmanagedType.U4)] out uint totalentries,
        [MarshalAs(UnmanagedType.U4)] out uint resume_handle
    );
#pragma warning restore CA1401 // P/Invokes 应该是不可见的
    /// <summary>
    /// 遍历某台电脑的共享文件
    /// </summary>
    /// <param name="server"></param>
    /// <returns></returns>
    public static string[]? GetNetShareList(string server)
    {
        //-1应该是获取所有的share,msdn里面的例子是这么写的,返回0表示成功
        if (NetShareEnum(server, 1, out IntPtr buffer, -1, out uint entriesread, out _, out _) != 0)
            return null;

        int ptr = buffer.ToInt32();
        var alShare = new List<string>();
        for (int i = 0; i < entriesread; i++)
        {
            var type = Marshal.PtrToStructure(new IntPtr(ptr), typeof(SHARE_INFO_1));
            if (type is null)
                continue;
            var shareInfo = (SHARE_INFO_1)type;
            if (shareInfo.shi1_type == 0)// Disk drive类型
                alShare.Add(shareInfo.shi1_netname);
            ptr += Marshal.SizeOf(shareInfo);
        }
        string[] share = new string[alShare.Count];
        for (int i = 0; i < alShare.Count; i++)
            share[i] = alShare[i];

        return share;
    }
}